#include <string.h>
#include <stdio.h>

#include "land_graphics.h"

#define LAND_OGL_CORE

#include "init.h"


static const char* SHADER_VERTEX_COLOR[] = {
"out vec4 outColor; \n"
"void main(){\n"
"    gl_Position = landProjection*landView*landTransform*landPosition;\n"
"    outColor = landColor; \n"
"}\n",

"in vec4 outColor; \n"
"void main(){ \n"
"    gl_FragColor = outColor; \n"
"}\n"
};

static const char* SHADER_COLOR_TEXTURE[] = {
"out vec4 outColor; \n"
"out vec2 outUv; \n"
"void main(){\n"
"    gl_Position = landProjection*landView*landTransform*landPosition;\n"
"    outColor = landColor;\n"
"    outUv = vec2(landUv.x, landUv.y);\n"
"}\n",

"in vec4 outColor; \n"
"in vec2 outUv; \n"
"uniform sampler2D landBaseTexture;\n"
"void main(){ \n"
"    gl_FragColor = texture2D(landBaseTexture, outUv) * outColor;\n"
"}\n"
};

static const char* SHADER_ALPHA_TEXTURE[] = {
"out vec4 outColor; \n"
"out vec2 outUv; \n"
"void main(){\n"
"    gl_Position = landProjection*landView*landTransform*landPosition;\n"
"    outColor = landColor;\n"
"    outUv = vec2(landUv.x, landUv.y);\n"
"}\n",

"in vec4 outColor; \n"
"in vec2 outUv; \n"
"uniform sampler2D landBaseTexture;\n"
"void main(){ \n"
"    vec4 texColor = texture2D(landBaseTexture, outUv); \n"
"    gl_FragColor = vec4(1.f, 1.f, 1.f, texColor.a) * outColor;\n"
"}\n"
};

static const char** SHADER_SOURCES[] = {
	SHADER_VERTEX_COLOR,
	SHADER_COLOR_TEXTURE,
	SHADER_ALPHA_TEXTURE,
};

static struct {
	int ok;
	LandShader* shaders[LAND_STD_SHADER_END];
}ctx = { 0 };

static LandShader*
newShader(LandStdShader e) {
    LandShader* shader = landNewShader();
	const char** srcs = SHADER_SOURCES[e];
    landShaderSource(shader,
		LAND_SHADER_VERTEX, srcs[0], strlen(srcs[0]));
    landShaderSource(shader,
        LAND_SHADER_FRAGMENT, srcs[1], strlen(srcs[1]));
	char* err;
	if (landCompileShader(shader, &err)) {
		printf("default shader error:%s\n", err);
		return NULL;
	}
	return shader;
}


static const char**
getShaderSource(LandStdShader e) {
	return SHADER_SOURCES[e];
}

static LandStdBackend backend = {
	newShader,
	getShaderSource,
};

LandStdBackend*
landGetOglStdBackend() {
	return &backend;
}

void
landInitOglStdContext(LandGraphics* config, LandOgl* oglConfig) {
}